package com.hc.testaudio.deletea.test1.ui;

import android.annotation.SuppressLint;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.charts.LineChart;
import com.hc.testaudio.R;

import com.hc.testaudio.deletea.test1.DataPoolUtil;
import com.hc.testaudio.deletea.test1.IMediaListener;
import com.hc.testaudio.deletea.test1.MediaUtil;
import com.hc.testaudio.deletea.test1.VisualizerUtil;
import com.hc.testaudio.deletea.test1.chart.BarChartUtil;
import com.hc.testaudio.deletea.test1.chart.LineChartUtil;
import com.hc.testaudio.deletea.ui.BaseActivity;
import com.hc.testaudio.deletea.util.forurier.FftUtil;
import com.yc.yclibx.comment.YcLog;
import com.yc.yclibx.comment.YcResources;
import com.yc.yclibx.file.YcFileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 *
 */
public class BarChartActivity extends BaseActivity {
//    val Hz = listOf(8000, 11025, 22050, 32000, 44100, 47250, 48000, 50000, 50400, 96000, 192000, 282240000)

    private MediaUtil mMediaUtil = new MediaUtil();
    private VisualizerUtil mVisualizerUtil = new VisualizerUtil();
    BarChartUtil mBarChartUtil;
    BarChartUtil mBarChartUtil2;
    LineChartUtil mLineChartUtil;
    private DataPoolUtil mDataPool = new DataPoolUtil();
    BarChart barChart;
    BarChart barChart2;
    LineChart lineChart;
    TextView chartStartBtn;
    private long time1;

    @Override
    protected int getLayoutId() {
        return R.layout.bar_chart_activity;
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        barChart = findViewById(R.id.barChart);
        barChart2 = findViewById(R.id.barChart2);
        lineChart = findViewById(R.id.lineChart);
        chartStartBtn = findViewById(R.id.chartStartBtn);
        mDataPool.setGetDataCall(new DataPoolUtil.GetDataCall() {
            @SuppressLint("CheckResult")
            @Override
            public void getData(int[] byteData, int samplingRate, int captureSize) {
                List<Float> dataY = new ArrayList<Float>();
                List<Float> dataX = new ArrayList<Float>();
                for (int i = 0; i < byteData.length; i++) {
                    float time = 1000f / (samplingRate / 1000f);
                    dataY.add((float) byteData[i]);
                    dataX.add((float) i);
                }
                mLineChartUtil.add(dataX, dataY);
                mLineChartUtil.invalidate();
                Observable.just(byteData)
                        .observeOn(Schedulers.newThread())//下游
                        .map(integer -> FftUtil.getFFt(integer))
                        .observeOn(AndroidSchedulers.mainThread())//下游
                        .subscribe(doubles -> show(doubles, samplingRate, captureSize, mBarChartUtil2));
            }
        });
        mBarChartUtil = new BarChartUtil(barChart, getActivity());
        mBarChartUtil2 = new BarChartUtil(barChart2, getActivity());
        mLineChartUtil = new LineChartUtil(lineChart, getActivity());
        mMediaUtil.setMMediaListener(new IMediaListener() {
            @Override
            public void onStartPlayingListener(MediaPlayer mp) {
                mVisualizerUtil.start(mp.getAudioSessionId()); //开始采集播放音频的数据
            }

            @Override
            public void onCompletionListener() {
                mVisualizerUtil.stop();
            }

            @Override
            public void onErrorListener() {
                mVisualizerUtil.stop();
            }
        });

        mVisualizerUtil.setMDataCaptureListener(new Visualizer.OnDataCaptureListener() {
            @Override
            public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
                if (visualizer == null || waveform == null || waveform.length <= 0) {
                    return;
                }
                if (waveform.length != 1024) {
                    YcLog.e("采样值不为：" + waveform.length);
                }
//                mDataPool.setSamplingRate(samplingRate);
//                mDataPool.add(waveform);
//                byte[] newData = new byte[waveform.length];
//                for (int i = 0; i < newData.length; i++) {
//                    if (waveform[i] == 0 || waveform[i] == -128) {
//                        newData[i] = 0;
//                    } else if (waveform[i] > 0) {
//                        newData[i] = (byte) (128 - waveform[i]);
//                    } else {
//                        newData[i] = (byte) ((waveform[i] + 128) * -1);
//                    }
//                }
//                mDataPool.add(newData);
//                double[] x = new double[waveform.length];
//                double[] y = new double[waveform.length];
//                for (int i = 0; i < x.length; i++) {
//                    if (waveform[i] == 0 || waveform[i] == -128) {
//                        x[i] = 0;
//                    } else {
//                        x[i] = waveform[i];
//                    }
//
//                    if (waveform[i] == 0 || waveform[i] == -128) {
//                        x[i] = 0;
//                    } else if (waveform[i] > 0) {
//                        x[i] = (byte) (128 - waveform[i]);
//                    } else {
//                        x[i] = (byte) ((waveform[i] + 128) * -1);
//                    }
//                }
//                fft.fft(x, y, 1);
//                double[] result = new double[waveform.length];//傅里叶变换只有前面一半数据有用
//                result[0] = x[0];          //DC直流分量 ；第一个数据没有虚部的
//                result[1] = x[waveform.length / 2]; //Nyquist 奈奎斯特频率；
//                for (int i = 2; i < waveform.length; i += 2) {    //FFT结果显示
//                    result[i] = YcCalculator.roundOff(x[i / 2], 2);
//                    result[i + 1] = YcCalculator.roundOff(y[i / 2], 2);
//                }
//                if (time1 == 0) {
//                    time1 = System.currentTimeMillis();
//                } else {
//                    long time2 = System.currentTimeMillis();
//                    YcLog.e("time:" + (time2 - time1));
//                    time1 = time2;
//                }

//                double[] fftData = FftUtil.getFFt(newData);
//                show(fftData, samplingRate, visualizer.getCaptureSize(), mBarChartUtil2);


                //                mDataPool.captureSize = samplingRate
                //                mDataPool.samplingRate = visualizer!!.captureSize
                //                mDataPool.add(waveform)
                //                YcLog.e("waveform数量：" + waveform!!.size)
                // 时域数据
                //                put(waveform)
//                                val standard = 12.283f //设置电压的基准值
                float standard = 10f; //设置电压的基准值
                if (waveform != null) {
                    List<Float> dataY = new ArrayList<Float>();
                    List<Float> dataX = new ArrayList<Float>();
                    YcLog.e("samplingRate：" + samplingRate);
                    float time = 1000f / (samplingRate / 1000f);
                    float max = 0f;
                    for (int i = 0; i < waveform.length; i++) {
                        float y;
                        if (waveform[i] == 0) {
                            y = 0;
                        } else if (waveform[i] > 0) {
                            y = (128 - waveform[i]) * standard / 128f;
                        } else {
                            y = ((waveform[i] + 128) * -1 * standard / 128f);
                        }
                        dataY.add(y);
                        dataX.add(i * time);
                    }
                    mLineChartUtil.add(dataX, dataY);
                    mLineChartUtil.invalidate();
                } else {
                    Toast.makeText(getActivity(), "时域数据为空", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
                //                YcLog.e("fft数量：" + fft!!.size)
                //频域数据
                if (fft == null) {
                    Toast.makeText(getActivity(), "频域数据为空", Toast.LENGTH_SHORT).show();
                } else {
                    show(fft, samplingRate, visualizer.getCaptureSize(), mBarChartUtil);
                }
            }
        });

        chartStartBtn.setOnClickListener(v -> {
//            getData();
            mMediaUtil.play();//开始播放音频
        });
    }

    private void getData() {
        try {
            InputStream is = getResources().openRawResource(R.raw.sin);
            byte[] buffer = new byte[1024];
            int byteCount;
            while ((byteCount = is.read(buffer)) != -1) {
                mDataPool.add2(buffer);
            }
            is.close();
        } catch (Exception e) {
            YcLog.e("复制assets文件出错：" + e.getMessage());
            e.printStackTrace();
        }
//        int time = (int) (1024 / 44100f * 1000);
//        Observable.interval(0, time, TimeUnit.MILLISECONDS)
//                .
    }

    private void show(byte[] fftData, int samplingRate, int captureSize, BarChartUtil barChartUtil) {
        int tempLength = fftData.length / 2 - 1;
//        int frequencyCounts = tempLength; //有效的fft数据 1+1+(fftData.size/2)（即有效的采样数）
        float[] magnitudes = new float[tempLength]; //振幅
        float[] phases = new float[tempLength]; //相位
        //fft数据里 第0个 和 第fft.size/2个 数据特殊只有实部
//        magnitudes[0] = Math.abs(fftData[0]);  // 直流
//        magnitudes[tempLength] = Math.abs(fftData[tempLength]);   // 实数
//        phases[0] = 0f;
//        phases[tempLength] = 0f;
        for (int k = 0; k < tempLength; k++) {
            int i = (k + 1) * 2;
            magnitudes[k] = (float) Math.hypot(fftData[i], fftData[i + 1]);
            phases[k] = (float) Math.atan2(fftData[i + 1], fftData[i]);
            if (magnitudes[k] > 0) {
                magnitudes[k] = (float) (20 * Math.log10(magnitudes[k]));
            }
        }

        float[] frequency = new float[tempLength];//频率
        float frequencyEach = samplingRate / 1000f / 1000 / captureSize; //频率间隔
        for (int i = 0; i < tempLength; i++) {
            frequency[i] = i * frequencyEach;
        }
        barChartUtil.add(frequency, magnitudes);
        barChartUtil.invalidate();
    }

    long time;

    private void show(double[] fftData, int samplingRate, int captureSize, BarChartUtil barChartUtil) {
        if (time == 0) {
            time = System.currentTimeMillis();
        } else {
            long time2 = System.currentTimeMillis();
            YcLog.e("时间" + (time2 - time));
            time = time2;
        }
        int tempLength = fftData.length / 2 - 1;
//        int frequencyCounts = tempLength; //有效的fft数据 1+1+(fftData.size/2)（即有效的采样数）
        float[] magnitudes = new float[tempLength]; //振幅
        float[] phases = new float[tempLength]; //相位
        //fft数据里 第0个 和 第fft.size/2个 数据特殊只有实部
//        magnitudes[0] = Math.abs(fftData[0]);  // 直流
//        magnitudes[tempLength] = Math.abs(fftData[tempLength]);   // 实数
//        phases[0] = 0f;
//        phases[tempLength] = 0f;
        for (int k = 0; k < tempLength; k++) {
            int i = (k + 1) * 2;
            magnitudes[k] = (float) Math.hypot(fftData[i], fftData[i + 1]);
            phases[k] = (float) Math.atan2(fftData[i + 1], fftData[i]);
            if (magnitudes[k] > 0) {
                magnitudes[k] = (float) (20 * Math.log10(magnitudes[k]));
            }
        }

        float[] frequency = new float[tempLength];//频率
        float frequencyEach = samplingRate / 1000f / 1000 / captureSize; //频率间隔
        for (int i = 0; i < tempLength; i++) {
            frequency[i] = i * frequencyEach;
        }
        barChartUtil.add(frequency, magnitudes);
        barChartUtil.invalidate();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mVisualizerUtil.stop();
    }
    //
    //    var frequency = 44100 //通用采样率
    //    val channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO
    //    val audioEncodeing = AudioFormat.ENCODING_PCM_16BIT
    //    var mAudioHelper = AudioHelper()
}